import { useState, useEffect, useCallback, useRef } from 'react'
import { ApiResponse, ApiError } from './request'

// Hook 配置选项
export interface UseRequestOptions<T> {
  manual?: boolean // 是否手动触发
  defaultParams?: unknown[] // 默认参数
  onSuccess?: (data: T, params?: unknown[]) => void // 成功回调
  onError?: (error: ApiError, params?: unknown[]) => void // 错误回调
  refreshDeps?: unknown[] // 依赖刷新
  debounceWait?: number // 防抖延迟
  throttleWait?: number // 节流延迟
}

// Hook 返回值
export interface UseRequestResult<T> {
  data: T | undefined
  loading: boolean
  error: ApiError | null
  run: (...params: unknown[]) => Promise<T>
  runAsync: (...params: unknown[]) => Promise<ApiResponse<T>>
  refresh: () => void
  cancel: () => void
  mutate: (data: T | ((oldData: T | undefined) => T)) => void
}

// 防抖和节流功能已简化，后续可扩展

export function useRequest<T = unknown>(
  service: (...args: unknown[]) => Promise<ApiResponse<T>>,
  options: UseRequestOptions<T> = {}
): UseRequestResult<T> {
  const {
    manual = false,
    defaultParams = [],
    onSuccess,
    onError,
    refreshDeps = [],
  } = options

  const [data, setData] = useState<T | undefined>(undefined)
  const [loading, setLoading] = useState<boolean>(false)
  const [error, setError] = useState<ApiError | null>(null)

  const latestParamsRef = useRef<unknown[]>(defaultParams)
  const cancelRef = useRef<boolean>(false)
  const countRef = useRef(0)

  // 执行请求
  const runAsync = useCallback(
    async (...params: unknown[]): Promise<ApiResponse<T>> => {
      const currentCount = ++countRef.current
      cancelRef.current = false
      setLoading(true)
      setError(null)
      latestParamsRef.current = params.length > 0 ? params : defaultParams

      try {
        const response = await service(...latestParamsRef.current)
        
        // 检查是否被取消
        if (cancelRef.current || currentCount !== countRef.current) {
          return response
        }

        setData(response.data)
        setLoading(false)
        onSuccess?.(response.data, latestParamsRef.current)
        return response
      } catch (err) {
        // 检查是否被取消
        if (cancelRef.current || currentCount !== countRef.current) {
          return Promise.reject(err)
        }

        const apiError = err as ApiError
        setError(apiError)
        setLoading(false)
        onError?.(apiError, latestParamsRef.current)
        return Promise.reject(apiError)
      }
    },
    [service, defaultParams, onSuccess, onError]
  )

  // 简化的执行方法（只返回 data）
  const run = useCallback(
    async (...params: unknown[]): Promise<T> => {
      const response = await runAsync(...params)
      return response.data
    },
    [runAsync]
  )

  // 刷新（使用上次的参数）
  const refresh = useCallback(() => {
    runAsync(...latestParamsRef.current)
  }, [runAsync])

  // 取消请求
  const cancel = useCallback(() => {
    cancelRef.current = true
    setLoading(false)
  }, [])

  // 手动更新数据
  const mutate = useCallback((newData: T | ((oldData: T | undefined) => T)) => {
    if (typeof newData === 'function') {
      setData((oldData) => (newData as (prev: T | undefined) => T)(oldData))
    } else {
      setData(newData)
    }
  }, [])

  // 使用原始的 run 函数
  const finalRun = run

  // 自动执行
  useEffect(() => {
    if (!manual) {
      finalRun(...defaultParams)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [manual, finalRun, defaultParams, ...refreshDeps])

  // 组件卸载时取消请求
  useEffect(() => {
    return () => {
      cancel()
    }
  }, [cancel])

  return {
    data,
    loading,
    error,
    run: finalRun,
    runAsync,
    refresh,
    cancel,
    mutate,
  }
}

// 专门用于分页的 Hook
export interface UsePaginationOptions<T> extends UseRequestOptions<T> {
  defaultCurrent?: number
  defaultPageSize?: number
}

export interface UsePaginationResult<T> extends UseRequestResult<T> {
  pagination: {
    current: number
    pageSize: number
    total: number
    totalPages: number
  }
  changePage: (page: number) => void
  changePageSize: (pageSize: number) => void
  reload: () => void
}

export function usePagination<T = unknown>(
  service: (params: {
    page: number
    pageSize: number
    [key: string]: unknown
  }) => Promise<ApiResponse<{ list: T[]; total: number; page: number; pageSize: number; totalPages: number }>>,
  options: UsePaginationOptions<{ list: T[]; total: number; page: number; pageSize: number; totalPages: number }> = {}
): {
  data: T[] | undefined
  loading: boolean
  error: ApiError | null
  pagination: {
    current: number
    pageSize: number
    total: number
    totalPages: number
  }
  changePage: (page: number) => void
  changePageSize: (pageSize: number) => void
  reload: () => void
} {
  const {
    defaultCurrent = 1,
    defaultPageSize = 10,
    ...restOptions
  } = options

  const [current, setCurrent] = useState(defaultCurrent)
  const [pageSize, setPageSize] = useState(defaultPageSize)

  const result = useRequest(
    (...args: unknown[]) => {
      const params = (args[0] as Record<string, unknown>) || {}
      return service({ page: current, pageSize, ...params })
    },
    {
      ...restOptions,
      defaultParams: [{}],
    }
  )

  const changePage = useCallback((page: number) => {
    setCurrent(page)
  }, [])

  const changePageSize = useCallback((size: number) => {
    setPageSize(size)
    setCurrent(1) // 重置到第一页
  }, [])

  const reload = useCallback(() => {
    result.refresh()
  }, [result])

  // 当页码或页面大小改变时，自动刷新
  useEffect(() => {
    result.run({})
  }, [current, pageSize, result])

  return {
    ...result,
    data: result.data?.list,
    pagination: {
      current,
      pageSize,
      total: result.data?.total || 0,
      totalPages: result.data?.totalPages || 0,
    },
    changePage,
    changePageSize,
    reload,
  }
}
